IF EXISTS (SELECT * FROM SYSOBJECTS WHERE name='spRecaudo' and XTYPE='P')
BEGIN
	DROP PROCEDURE [dbo].[spRecaudo]
END
GO
CREATE PROCEDURE [dbo].[spRecaudo]
	 @OP VARCHAR(64)=NULL
	,@ParamAuxiliar NVARCHAR(MAX)=NULL   /* PARAMETRO AUXILIAR */
	,@ID INT=NULL
	,@FechaGrab SMALLDATETIME=NULL
	,@UsuarioGrab VARCHAR(32)=NULL
	,@CodRecaudo INT=NULL
	,@CodPlaca VARCHAR(8)=NULL
	,@Observaciones VARCHAR(512)=NULL
	,@ValorAdicional NUMERIC(18,2)=NULL
WITH ENCRYPTION
AS
SET NOCOUNT ON
BEGIN TRY

DECLARE @AUX NVARCHAR(2048)
DECLARE @indice	INTEGER		--- Esta variable es necesaria para mapear el XML
DECLARE @ConsecutivoTemp	INTEGER
DECLARE @SubTotalRecaudos NUMERIC(18,2)
DECLARE @SubTotalDevoluciones NUMERIC(18,2)
DECLARE @Cartulinas TABLE(NumeroCartulina INT, CodPlaca VARCHAR(8))

/*****     OPERACION POR DEFECTO    *****/
IF @OP IS NULL OR @OP = ''
BEGIN
	SELECT
		t.*
	FROM
		[dbo].[Recaudo] t
	ORDER BY
		t.FechaGrab DESC	
RETURN 0
END

/*****   GENERAR EL RECAUDO  *****/
IF @OP = 'GenerarRecaudo'
BEGIN	
	BEGIN TRANSACTION
	
	----------------------------------------------------------------------------------------------
	-- Inserto el Detalle del registro
	----------------------------------------------------------------------------------------------
	EXEC sp_xml_preparedocument @indice OUTPUT, @ParamAuxiliar
	
	INSERT INTO  @Cartulinas
		([NumeroCartulina],[CodPlaca])
	SELECT 	
		[NumeroCartulina],@CodPlaca
	FROM OPENXML(@indice,'/DocumentElement/XML_TABLE',2)WITH 
		([NumeroCartulina] INT)
		
	EXEC sp_xml_removedocument @indice	
	
	--- Verifico si La Placa se encuentra Inactiva
	if exists (select top 1 CodPlaca from Placa Where CodPlaca=@CodPlaca AND Activo=0)
	begin
		SET @AUX='La placa "'+@CodPlaca+'" Se encuentra INACTIVA. Verifique!'
		RAISERROR(@AUX,16,1)
		RETURN 1
	end
	--- Verifico si el Tipo de Cartulina Asociado a la Placa se encuentra INACTIVO
	if exists (select top 1 CodPlaca from Placa p INNER JOIN CartulinaTipo t ON p.CodCartulinaTipo=t.CodCartulinaTipo Where CodPlaca=@CodPlaca AND t.Activo=0)
	begin
		select top 1 @AUX='El Tipo de Cartulina "'+CodCartulinaTipo+'" Asociado a la placa "'+CodPlaca+'" Se encuentra INACTIVO. Verifique!' from Placa WHERE CodPlaca=@CodPlaca
		RAISERROR(@AUX,16,1)
		RETURN 1
	end
	
	--- Verifico si hay cartulinas repetidas
	if exists (select top 1 numeroCartulina from @Cartulinas group by numeroCartulina having COUNT(*)>1)
	begin
		SELECT TOP 1 @AUX='La cartulina Numero '+CONVERT(varchar(8),numeroCartulina)+' esta repetida.' FROM @Cartulinas group by numeroCartulina having COUNT(*)>1
		RAISERROR(@AUX,16,1)
		RETURN 1
	end
	
	--- Verifico si hay cartulinas que ya existen en la tabla "Cartulina"
	if exists (select top 1 * from Cartulina where CodCartulina in (select numeroCartulina from @Cartulinas))
	begin
		SET @AUX='Las siguiente(s) Cartulina(s) se encuentra(n) registrada(s) en la base de datos. Verifique!'+CHAR(10)
		SELECT @AUX=@AUX+'	-'+ CONVERT(VARCHAR(8),CodCartulina)+CHAR(10) from Cartulina where CodCartulina in (select numeroCartulina from @Cartulinas)
		RAISERROR(@AUX,16,1)
		RETURN 1
	end
	
	--- Verifico si hay cartulinas que ya existen en la tabla "Devolucion"
	if exists (select top 1 * from CartulinaDevoluciones where CodCartulinaNueva in (select numeroCartulina from @Cartulinas))
	begin
		SET @AUX='Las siguiente(s) Cartulina(s) se encuentra(n) registrada(s) en la base de datos. Verifique!'+CHAR(10)
		SELECT @AUX=@AUX+'	-'+ CONVERT(VARCHAR(8),CodCartulinaNueva)+CHAR(10) from CartulinaDevoluciones where CodCartulinaNueva in (select numeroCartulina from @Cartulinas)
		RAISERROR(@AUX,16,1)
		RETURN 1
	end
	
	--- Obtengo el Proximo Consecutivo
	EXEC [spSeguridadConsecutivos] @OP='ObtenerProximoConsecutivo',@CodConsecutivo='Recaudos',@ProximoConsecutivo=@ConsecutivoTemp OUTPUT
	
	--- Grabo la accion en el log
	SET @AUX='Codigo Recaudo: '+CONVERT(VARCHAR(8),@ConsecutivoTemp)
	EXEC dbo.spSeguridadLogEventos_Insert @Evento='GENERACION DE RECAUDO',@Detalle=@AUX
	
	--- Guardo la informacion en la tabla Recaudos
	INSERT INTO Recaudo	
		(FechaGrab,UsuarioGrab,CodRecaudo,CodPlaca,Observaciones,ValorAdicional)
	VALUES
		(GETDATE(),dbo.fnGetUsuarioSession(),@ConsecutivoTemp,@CodPlaca,@Observaciones,@ValorAdicional)
	
	--- Obtengo el valor de la cartulina y grabo los datos basicos de las mismas
	Insert into Cartulina
		(FechaGrab,UsuarioGrab,CodCartulina,CodRecaudo,CodCartulinaEstado,ValorCartulina,ValorTransMasivo,ValorUtilidad,ValorObligaciones)
	select 
		GETDATE(),
		dbo.fnGetUsuarioSession(),
		c.NumeroCartulina,
		@ConsecutivoTemp,
		'ACTIVO',
		ct.ValorCartulina,
		ct.ValorTransMasivo,
		ct.ValorCartulina - ct.ValorTransMasivo - SUM(Case when o.Porcentaje=0 then o.Valor*(CASE WHEN ot.Naturaleza='DB' THEN 1 ELSE -1 END)  else (ct.ValorCartulina-ct.ValorTransMasivo) * o.Porcentaje / 100 *(CASE WHEN ot.Naturaleza='DB' THEN 1 ELSE -1 END) end) AS TotalUtilidad,
		SUM(Case when o.Porcentaje=0 then o.Valor*(CASE WHEN ot.Naturaleza='DB' THEN 1 ELSE -1 END)  else (ct.ValorCartulina-ct.ValorTransMasivo) * o.Porcentaje / 100 *(CASE WHEN ot.Naturaleza='DB' THEN 1 ELSE -1 END) end) AS ValorObligaciones
	FROM
		@Cartulinas c	
		INNER JOIN Placa p 
			ON c.CodPlaca=p.CodPlaca
		INNER JOIN CartulinaTipo ct
			ON p.CodCartulinaTipo=ct.CodCartulinaTipo
		INNER JOIN CartulinaTipo_Obligacion cto
			ON p.CodCartulinaTipo=cto.CodCartulinaTipo			
		INNER JOIN obligacion o
			ON cto.CodObligacion=o.CodObligacion
			AND o.Activo=1
		INNER JOIN ObligacionTipo ot
			ON o.CodObligacionTipo=ot.CodObligacionTipo
			AND ot.Activo=1
	group by
		c.NumeroCartulina,
		ct.ValorCartulina,
		ct.ValorTransMasivo
	
	--- grabo las obligaciones asociadas al tipo de cartulina en la tabla Cartulina_Obligacion
	insert into Cartulina_Obligacion
		(FechaGrab,UsuarioGrab,CodCartulina,CodObligacion,DescripcionObligacion,PorcentajeObligacion,ValorObligacion)
	select 
		GETDATE(),
		dbo.fnGetUsuarioSession(),
		c.NumeroCartulina,
		o.CodObligacion,
		o.Descripcion,
		o.Porcentaje,
		Case when o.Porcentaje=0 then o.Valor*(CASE WHEN ot.Naturaleza='DB' THEN 1 ELSE -1 END) else (ct.ValorCartulina-ct.ValorTransMasivo) * o.Porcentaje / 100 * (CASE WHEN ot.Naturaleza='DB' THEN 1 ELSE -1 END) end AS Valor
	FROM
		@Cartulinas c	
		INNER JOIN Placa p 
			ON c.CodPlaca=p.CodPlaca
		INNER JOIN CartulinaTipo ct
			ON p.CodCartulinaTipo=ct.CodCartulinaTipo
		INNER JOIN CartulinaTipo_Obligacion cto
			ON p.CodCartulinaTipo=cto.CodCartulinaTipo
		INNER JOIN obligacion o
			ON cto.CodObligacion=o.CodObligacion
			AND o.Activo=1
		INNER JOIN ObligacionTipo ot
			ON o.CodObligacionTipo=ot.CodObligacionTipo
			AND ot.Activo=1
						
	--- Incremento el valor del consecutivo "Cartulinas"
	SELECT @indice=ISNULL(MAX(CodCartulina),0) 
		FROM Cartulina

	SELECT @indice=CASE WHEN @indice<ISNULL(MAX(CodCartulinaNueva),0) THEN ISNULL(MAX(CodCartulinaNueva),0) ELSE @indice END 
		FROM CartulinaDevoluciones

	UPDATE 
		[dbo].[SeguridadConsecutivos] 
	SET 
		FechaUltModific=GETDATE(),
		UsuarioUltModific=dbo.fnGetUsuarioSession(),
		ProximoConsecutivo=@indice+1 
	WHERE 
		CodConsecutivo='Cartulinas'	
	
	--- Retorno la informacion necesaria para imprimir el Ticket Correspondiente al Recaudo generado
	SET @AUX='EXEC '+OBJECT_NAME(@@PROCID)+' @OP=''RetornarInformacionTicketRecaudo'', @CodRecaudo='+CONVERT(NVARCHAR(8),@ConsecutivoTemp)
	EXEC sp_executeSql @AUX
	
	
	COMMIT TRANSACTION
	RETURN 0
END

/*****   RETORNO LA INFORMACION NECESARIA PARA IMPRIMIR EL TICKET CORRESPONDIENTE AL RECAUDO GENERADO  *****/
IF @OP='RetornarInformacionTicketRecaudo'
BEGIN
	
	IF @ParamAuxiliar IS NOT NULL
	BEGIN
		--- Grabo la accion en el log
		SET @AUX='Codigo Recaudo: '+CONVERT(VARCHAR(8),@CodRecaudo)+'. '+CHAR(10)+'Motivo: '+@ParamAuxiliar
		EXEC dbo.spSeguridadLogEventos_Insert @Evento='REIMPRESION DE TICKET (RECAUDO)',@Detalle=@AUX
	END
	
	--Lista de cartulinas
	SET @AUX = 
		STUFF((
				SELECT	',' + CONVERT(VARCHAR(8),CodCartulina)
				FROM	Cartulina
				WHERE	CodRecaudo=@CodRecaudo
				ORDER BY	CodCartulina ASC
				FOR XML PATH(''), TYPE
			).value('.', 'NVARCHAR(MAX)'),1,1,'')
	
	SET @AUX=REPLACE(@AUX,',',', ')
	
	-- Numero de cartulinas
	SELECT @indice = COUNT(*) FROM Cartulina Where CodRecaudo=@CodRecaudo
	
	
	-- Retorno la informacion
	SELECT
		 r.FechaGrab
		,RIGHT(REPLICATE('0',8)+CONVERT(VARCHAR(8),r.CodRecaudo),8) AS CodRecaudo
		,r.CodPlaca
		,@AUX AS Cartulinas
		,@indice As NumeroCartulinas
		,dbo.fnFormatoMoneda((SELECT SUM(cc.ValorCartulina) FROM Cartulina cc WHERE cc.CodRecaudo=r.CodRecaudo)) AS SubTotal
		,dbo.fnFormatoMoneda(r.ValorAdicional) as ValorAdicional
		,dbo.fnFormatoMoneda((SELECT SUM(cc.ValorCartulina) FROM Cartulina cc WHERE cc.CodRecaudo=r.CodRecaudo)+r.ValorAdicional) AS [Total]
		,r.Observaciones
		,u.UserName
	FROM 
		Recaudo r
		Inner join SeguridadUsuario u
			ON r.UsuarioGrab=u.Login
	WHERE
		CodRecaudo=@CodRecaudo
RETURN 0
END

/*****   RETORNAR TOTAL VENTAS PARA EL DIA DE HOY  *****/
IF @OP='ObtenerTotalVendidoHoy'
BEGIN
	
	---declare @Fecha date =CONVERT(date,'2012/12/13',111)
	
	--select * from Recaudo where CONVERT(VARCHAR(10),FechaGrab,111) BETWEEN @ParamAuxiliar AND @Observaciones
	
	set @SubTotalRecaudos=0
	set @SubTotalDevoluciones=0
	--- Sumo los adicionales
	select @SubTotalRecaudos=@SubTotalRecaudos+SUM(ValorAdicional) from Recaudo where CONVERT(VARCHAR(10),FechaGrab,111) BETWEEN @ParamAuxiliar AND @Observaciones
	--- Sumo las cartulinas
	select @SubTotalRecaudos=@SubTotalRecaudos+SUM(ValorCartulina) from Cartulina where CONVERT(VARCHAR(10),FechaGrab,111) BETWEEN @ParamAuxiliar AND @Observaciones
	--- Sumo las devoluciones
	select @SubTotalDevoluciones=@SubTotalDevoluciones+SUM(Valor) from CartulinaDevoluciones where CONVERT(VARCHAR(10),FechaGrab,111) BETWEEN @ParamAuxiliar AND @Observaciones
	
	set @SubTotalRecaudos=ISNULL(@SubTotalRecaudos,0)
	set @SubTotalDevoluciones=ISNULL(@SubTotalDevoluciones,0)
	-- Retorno la informacion
	SELECT
		 dbo.fnFormatoMoneda(@SubTotalRecaudos) as SubTotalRecaudos
		,dbo.fnFormatoMoneda(@SubTotalDevoluciones) as SubTotalDevoluciones
		,dbo.fnFormatoMoneda(@SubTotalRecaudos+@SubTotalDevoluciones) as Total
		
RETURN 0
END


--- Si se llega a este punto es porque el @OP indicado no Existe en el Procedimiento Almacenado
IF @OP IS NOT NULL
	BEGIN
	SET @ParamAuxiliar='La Operacion "'+@OP+'" No esta definida en el Procedimiento almacenado "'+OBJECT_NAME(@@PROCID)+'", Revise!.'
	RAISERROR(@ParamAuxiliar,16,1)
	RETURN 1
END

--- CONTROLAR Y REGISTRAR LOS ERRORES
END TRY
BEGIN CATCH
	--- Recopilo la informacion del error
	DECLARE @ERROR_NUMBER INT=ERROR_NUMBER(),@ERROR_SEVERITY INT=ERROR_SEVERITY(),@ERROR_STATE INT=ERROR_STATE(),@ERROR_PROCEDURE VARCHAR(128)=ERROR_PROCEDURE(),@ERROR_LINE INT=ERROR_LINE(),@ERROR_MESSAGE VARCHAR(2048)=ERROR_MESSAGE()
	--- Si hay transacciones abiertas, hago un rollback, SE ENCIERRA EN UN (TRY-CATCH) PARA QUE NO SE MUESTRE EL ERROR: Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT
	IF(@@TRANCOUNT>0) BEGIN BEGIN TRY ROLLBACK TRANSACTION END TRY BEGIN CATCH END CATCH END
	--- Ejecuto el SP que controla y registra el error
	EXEC [spSeguridadMessageException] @OP='MostrarMensaje',@ERROR_NUMBER=@ERROR_NUMBER,@ERROR_SEVERITY=@ERROR_SEVERITY,@ERROR_STATE=@ERROR_STATE,@ERROR_PROCEDURE=@ERROR_PROCEDURE,@ERROR_LINE=@ERROR_LINE,@ERROR_MESSAGE=@ERROR_MESSAGE
	RETURN 1
END CATCH;
